// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// T [author] rhyme_lph
// A [email]  rhymelph@gmail.com
// M [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:dio/src/response.dart';
import 'package:finance_app/src/entities/invoice_entity.dart';
import 'package:finance_app/src/http_service/http_invoice_service.dart';
import 'package:finance_app/src/mixin/format_group_map_mixin.dart';
import 'package:finance_app/src/mixin/refresh_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/reg_exp_utils.dart';

class RecordPaymentProvider extends BaseProvider<List<InvoiceEntity>>
    with
        SearchDataListMixin,
        FormatGroupMapLocalMixin<InvoiceEntity>,
        RefreshMixin<List<InvoiceEntity>, List<InvoiceEntity>> {
  List<InvoiceEntity> invoiceList = [];

  @override
  Future get dataFuture => HttpInvoiceService.invoiceList(page);

  @override
  void searchRefreshData(searchData) {
    transformData(data, false);
    update();
  }

  void onCancel() {
    invoiceList.clear();
    transformData(data, false);
    update();
  }

  void onAdd() {
    if (invoiceList.length > 0) {
      double total = 0.0;
      invoiceList.forEach((element) {
        total += element.total.toDouble();
      });
      Routes.navigateTo(RouterGenProviders.newCashInPage,
          params: {
            'invoiceList': invoiceList,
            'total': total,
          },
          replace: true);
    }
  }

  void onSelect(InvoiceEntity item1) {
    if (invoiceList.contains(item1)) {
      invoiceList.remove(item1);
    } else {
      invoiceList.add(item1);
    }
    transformData(data, false);
    update();
  }

  void contactToMap(List<InvoiceEntity> list) {
    sortGroupToMap(list,
        sort: (a, b) => sortIssuesAt(a, b, (t) => t.issuedAt, (t) => t.id),
        group: (a) => groupMonth(a, (t) => t.issuedAt),
        filter: _handleFilter);
  }

  bool _handleFilter(InvoiceEntity a) {
    bool listFilter = false;
    if (invoiceList.length == 0) {
      listFilter = RegExpUtils.getSearchRegExp(searchController.text)
          .hasMatch(a.contact.name);
    } else if (invoiceList.length > 0) {
      final first = invoiceList.first;
      listFilter = first.contact.id == a.contact.id;
    }
    return listFilter && a.status == 'open';
  }

  @override
  FutureOr<List<InvoiceEntity>> transformData(
      List<InvoiceEntity> d, bool isCache) {
    groupMap.clear();
    contactToMap(d);
    return super.transformData(d, isCache);
  }

  @override
  List<InvoiceEntity> get dataList => data;

  @override
  List<InvoiceEntity> getFromRequestResult(Response result, bool isRefresh) {
    return getEntityFromResult(result);
  }

  @override
  Future get refreshFuture => dataFuture;
}
